{
    "description": "Patient concierge system that always verify the user's identity first before proceeding to answer user questions",
    "framework": ["Langchain"],
    "usecases": ["Chatbot"],
    "nodes": [
        {
            "id": "seqAgent_0",
            "position": {
                "x": 775.8784674767973,
                "y": -222.95218911189113
            },
            "type": "customNode",
            "data": {
                "id": "seqAgent_0",
                "label": "Agent",
                "version": 2,
                "name": "seqAgent",
                "type": "Agent",
                "baseClasses": ["Agent"],
                "category": "Sequential Agents",
                "description": "Agent that can execute tools",
                "inputParams": [
                    {
                        "label": "Agent Name",
                        "name": "agentName",
                        "type": "string",
                        "placeholder": "Agent",
                        "id": "seqAgent_0-input-agentName-string"
                    },
                    {
                        "label": "System Prompt",
                        "name": "systemMessagePrompt",
                        "type": "string",
                        "rows": 4,
                        "optional": true,
                        "default": "You are a research assistant who can search for up-to-date info using search engine.",
                        "id": "seqAgent_0-input-systemMessagePrompt-string"
                    },
                    {
                        "label": "Human Prompt",
                        "name": "humanMessagePrompt",
                        "type": "string",
                        "description": "This prompt will be added at the end of the messages as human message",
                        "rows": 4,
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_0-input-humanMessagePrompt-string"
                    },
                    {
                        "label": "Require Approval",
                        "name": "interrupt",
                        "description": "Require approval before executing tools. Will proceed when tools are not called",
                        "type": "boolean",
                        "optional": true,
                        "id": "seqAgent_0-input-interrupt-boolean"
                    },
                    {
                        "label": "Format Prompt Values",
                        "name": "promptValues",
                        "description": "Assign values to the prompt variables. You can also use $flow.state.<variable-name> to get the state value",
                        "type": "json",
                        "optional": true,
                        "acceptVariable": true,
                        "list": true,
                        "id": "seqAgent_0-input-promptValues-json"
                    },
                    {
                        "label": "Approval Prompt",
                        "name": "approvalPrompt",
                        "description": "Prompt for approval. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "You are about to execute tool: {tools}. Ask if user want to proceed",
                        "rows": 4,
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_0-input-approvalPrompt-string"
                    },
                    {
                        "label": "Approve Button Text",
                        "name": "approveButtonText",
                        "description": "Text for approve button. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "Yes",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_0-input-approveButtonText-string"
                    },
                    {
                        "label": "Reject Button Text",
                        "name": "rejectButtonText",
                        "description": "Text for reject button. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "No",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_0-input-rejectButtonText-string"
                    },
                    {
                        "label": "Update State",
                        "name": "updateStateMemory",
                        "type": "tabs",
                        "tabIdentifier": "selectedUpdateStateMemoryTab",
                        "additionalParams": true,
                        "default": "updateStateMemoryUI",
                        "tabs": [
                            {
                                "label": "Update State (Table)",
                                "name": "updateStateMemoryUI",
                                "type": "datagrid",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\n1. Key and value pair to be updated. For example: if you have the following State:\n    | Key       | Operation     | Default Value     |\n    |-----------|---------------|-------------------|\n    | user      | Replace       |                   |\n\n    You can update the \"user\" value with the following:\n    | Key       | Value     |\n    |-----------|-----------|\n    | user      | john doe  |\n\n2. If you want to use the agent's output as the value to update state, it is available as available as `$flow.output` with the following structure:\n    ```json\n    {\n        \"output\": \"Hello! How can I assist you today?\",\n        \"usedTools\": [\n            {\n                \"tool\": \"tool-name\",\n                \"toolInput\": \"{foo: var}\",\n                \"toolOutput\": \"This is the tool's output\"\n            }\n        ],\n        \"sourceDocuments\": [\n            {\n                \"pageContent\": \"This is the page content\",\n                \"metadata\": \"{foo: var}\",\n            }\n        ],\n    }\n    ```\n\n    For example, if the `toolOutput` is the value you want to update the state with, you can do the following:\n    | Key       | Value                                     |\n    |-----------|-------------------------------------------|\n    | user      | `$flow.output.usedTools[0].toolOutput`  |\n\n3. You can get default flow config, including the current \"state\":\n    - `$flow.sessionId`\n    - `$flow.chatId`\n    - `$flow.chatflowId`\n    - `$flow.input`\n    - `$flow.state`\n\n4. You can get custom variables: `$vars.<variable-name>`\n\n"
                                },
                                "description": "This is only applicable when you have a custom State at the START node. After agent execution, you might want to update the State values",
                                "datagrid": [
                                    {
                                        "field": "key",
                                        "headerName": "Key",
                                        "type": "asyncSingleSelect",
                                        "loadMethod": "loadStateKeys",
                                        "flex": 0.5,
                                        "editable": true
                                    },
                                    {
                                        "field": "value",
                                        "headerName": "Value",
                                        "type": "freeSolo",
                                        "valueOptions": [
                                            {
                                                "label": "Agent Output (string)",
                                                "value": "$flow.output.content"
                                            },
                                            {
                                                "label": "Used Tools (array)",
                                                "value": "$flow.output.usedTools"
                                            },
                                            {
                                                "label": "First Tool Output (string)",
                                                "value": "$flow.output.usedTools[0].toolOutput"
                                            },
                                            {
                                                "label": "Source Documents (array)",
                                                "value": "$flow.output.sourceDocuments"
                                            },
                                            {
                                                "label": "Global variable (string)",
                                                "value": "$vars.<variable-name>"
                                            },
                                            {
                                                "label": "Input Question (string)",
                                                "value": "$flow.input"
                                            },
                                            {
                                                "label": "Session Id (string)",
                                                "value": "$flow.sessionId"
                                            },
                                            {
                                                "label": "Chat Id (string)",
                                                "value": "$flow.chatId"
                                            },
                                            {
                                                "label": "Chatflow Id (string)",
                                                "value": "$flow.chatflowId"
                                            }
                                        ],
                                        "editable": true,
                                        "flex": 1
                                    }
                                ],
                                "optional": true,
                                "additionalParams": true
                            },
                            {
                                "label": "Update State (Code)",
                                "name": "updateStateMemoryCode",
                                "type": "code",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\n1. Return the key value JSON object. For example: if you have the following State:\n    ```json\n    {\n        \"user\": null\n    }\n    ```\n\n    You can update the \"user\" value by returning the following:\n    ```js\n    return {\n        \"user\": \"john doe\"\n    }\n    ```\n\n2. If you want to use the agent's output as the value to update state, it is available as `$flow.output` with the following structure:\n    ```json\n    {\n        \"content\": \"Hello! How can I assist you today?\",\n        \"usedTools\": [\n            {\n                \"tool\": \"tool-name\",\n                \"toolInput\": \"{foo: var}\",\n                \"toolOutput\": \"This is the tool's output\"\n            }\n        ],\n        \"sourceDocuments\": [\n            {\n                \"pageContent\": \"This is the page content\",\n                \"metadata\": \"{foo: var}\",\n            }\n        ],\n    }\n    ```\n\n    For example, if the `toolOutput` is the value you want to update the state with, you can return the following:\n    ```js\n    return {\n        \"user\": $flow.output.usedTools[0].toolOutput\n    }\n    ```\n\n3. You can also get default flow config, including the current \"state\":\n    - `$flow.sessionId`\n    - `$flow.chatId`\n    - `$flow.chatflowId`\n    - `$flow.input`\n    - `$flow.state`\n\n4. You can get custom variables: `$vars.<variable-name>`\n\n"
                                },
                                "description": "This is only applicable when you have a custom State at the START node. After agent execution, you might want to update the State values. Must return an object representing the state",
                                "hideCodeExecute": true,
                                "codeExample": "const result = $flow.output;\n\n/* Suppose we have a custom State schema like this:\n* {\n    aggregate: {\n        value: (x, y) => x.concat(y),\n        default: () => []\n    }\n  }\n*/\n\nreturn {\n  aggregate: [result.content]\n};",
                                "optional": true,
                                "additionalParams": true
                            }
                        ],
                        "id": "seqAgent_0-input-updateStateMemory-tabs"
                    },
                    {
                        "label": "Max Iterations",
                        "name": "maxIterations",
                        "type": "number",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_0-input-maxIterations-number"
                    }
                ],
                "inputAnchors": [
                    {
                        "label": "Tools",
                        "name": "tools",
                        "type": "Tool",
                        "list": true,
                        "optional": true,
                        "id": "seqAgent_0-input-tools-Tool"
                    },
                    {
                        "label": "Start | Agent | Condition | LLM | Tool Node",
                        "name": "sequentialNode",
                        "type": "Start | Agent | Condition | LLMNode | ToolNode",
                        "list": true,
                        "id": "seqAgent_0-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode"
                    },
                    {
                        "label": "Chat Model",
                        "name": "model",
                        "type": "BaseChatModel",
                        "optional": true,
                        "description": "Overwrite model to be used for this agent",
                        "id": "seqAgent_0-input-model-BaseChatModel"
                    }
                ],
                "inputs": {
                    "agentName": "Concierge",
                    "systemMessagePrompt": "You are the Assistant in our Patient Concierge system. The patient has verified their identity and is now allowed access to only their information. \n\nUse the function tool \"patient_information_database\" to look up patient procedures that match the Patient's name and ID with \"patient_name\" and \"user_id\" in that database. \n\nDo not make up information if it is not represented in the function tool database calls. Use this date format when to referring to dates in the databases: MM-DD-YYYY\n\nDO NOT ALLOW PATIENTS TO PROCEDE TO ACCESS OTHER PATIENT INFORMATION OR IT MAY RESULT IN A PHI VIOLATION.",
                    "humanMessagePrompt": "",
                    "tools": ["{{customTool_1.data.instance}}"],
                    "sequentialNode": ["{{seqCondition_0.data.instance}}", "{{seqCondition_0.data.instance}}"],
                    "model": "",
                    "interrupt": "",
                    "promptValues": "",
                    "approvalPrompt": "You are about to execute tool: {tools}. Ask if user want to proceed",
                    "approveButtonText": "Yes",
                    "rejectButtonText": "No",
                    "updateStateMemory": "updateStateMemoryUI",
                    "maxIterations": "",
                    "selectedUpdateStateMemoryTab_seqAgent_0": "updateStateMemoryUI"
                },
                "outputAnchors": [
                    {
                        "id": "seqAgent_0-output-seqAgent-Agent",
                        "name": "seqAgent",
                        "label": "Agent",
                        "description": "Agent that can execute tools",
                        "type": "Agent"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 877,
            "selected": false,
            "positionAbsolute": {
                "x": 775.8784674767973,
                "y": -222.95218911189113
            },
            "dragging": false
        },
        {
            "id": "seqEnd_0",
            "position": {
                "x": 1144.7214148311145,
                "y": 493.7324360922404
            },
            "type": "customNode",
            "data": {
                "id": "seqEnd_0",
                "label": "End",
                "version": 2,
                "name": "seqEnd",
                "type": "End",
                "baseClasses": ["End"],
                "category": "Sequential Agents",
                "description": "End conversation",
                "inputParams": [],
                "inputAnchors": [
                    {
                        "label": "Agent | Condition | LLM | Tool Node",
                        "name": "sequentialNode",
                        "type": "Agent | Condition | LLMNode | ToolNode",
                        "id": "seqEnd_0-input-sequentialNode-Agent | Condition | LLMNode | ToolNode"
                    }
                ],
                "inputs": {
                    "sequentialNode": "{{seqAgent_0.data.instance}}"
                },
                "outputAnchors": [],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 143,
            "positionAbsolute": {
                "x": 1144.7214148311145,
                "y": 493.7324360922404
            },
            "selected": false,
            "dragging": false
        },
        {
            "id": "seqState_0",
            "position": {
                "x": -339.5104253267711,
                "y": 713.8647069088731
            },
            "type": "customNode",
            "data": {
                "id": "seqState_0",
                "label": "State",
                "version": 2,
                "name": "seqState",
                "type": "State",
                "baseClasses": ["State"],
                "category": "Sequential Agents",
                "description": "A centralized state object, updated by nodes in the graph, passing from one node to another",
                "inputParams": [
                    {
                        "label": "Custom State",
                        "name": "stateMemory",
                        "type": "tabs",
                        "tabIdentifier": "selectedStateTab",
                        "additionalParams": true,
                        "default": "stateMemoryUI",
                        "tabs": [
                            {
                                "label": "Custom State (Table)",
                                "name": "stateMemoryUI",
                                "type": "datagrid",
                                "description": "Structure for state. By default, state contains \"messages\" that got updated with each message sent and received.",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\nSpecify the Key, Operation Type, and Default Value for the state object. The Operation Type can be either \"Replace\" or \"Append\".\n\n**Replace**\n- Replace the existing value with the new value.\n- If the new value is null, the existing value will be retained.\n\n**Append**\n- Append the new value to the existing value.\n- Default value can be empty or an array. Ex: [\"a\", \"b\"]\n- Final value is an array.\n"
                                },
                                "datagrid": [
                                    {
                                        "field": "key",
                                        "headerName": "Key",
                                        "editable": true
                                    },
                                    {
                                        "field": "type",
                                        "headerName": "Operation",
                                        "type": "singleSelect",
                                        "valueOptions": ["Replace", "Append"],
                                        "editable": true
                                    },
                                    {
                                        "field": "defaultValue",
                                        "headerName": "Default Value",
                                        "flex": 1,
                                        "editable": true
                                    }
                                ],
                                "optional": true,
                                "additionalParams": true
                            },
                            {
                                "label": "Custom State (Code)",
                                "name": "stateMemoryCode",
                                "type": "code",
                                "description": "JSON object representing the state",
                                "hideCodeExecute": true,
                                "codeExample": "{\n    aggregate: {\n        value: (x, y) => x.concat(y), // here we append the new message to the existing messages\n        default: () => []\n    }\n}",
                                "optional": true,
                                "additionalParams": true
                            }
                        ],
                        "id": "seqState_0-input-stateMemory-tabs"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "stateMemory": "stateMemoryUI",
                    "selectedStateTab_seqState_0": "stateMemoryUI",
                    "stateMemoryUI": "[{\"key\":\"userInfo\",\"type\":\"Replace\",\"defaultValue\":\"\",\"actions\":\"\",\"id\":1}]"
                },
                "outputAnchors": [
                    {
                        "id": "seqState_0-output-seqState-State",
                        "name": "seqState",
                        "label": "State",
                        "description": "A centralized state object, updated by nodes in the graph, passing from one node to another",
                        "type": "State"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 251,
            "selected": false,
            "positionAbsolute": {
                "x": -339.5104253267711,
                "y": 713.8647069088731
            },
            "dragging": false
        },
        {
            "id": "seqStart_0",
            "position": {
                "x": 60.339339995889304,
                "y": 396.3093919995337
            },
            "type": "customNode",
            "data": {
                "id": "seqStart_0",
                "label": "Start",
                "version": 2,
                "name": "seqStart",
                "type": "Start",
                "baseClasses": ["Start"],
                "category": "Sequential Agents",
                "description": "Starting point of the conversation",
                "inputParams": [],
                "inputAnchors": [
                    {
                        "label": "Chat Model",
                        "name": "model",
                        "type": "BaseChatModel",
                        "description": "Only compatible with models that are capable of function calling: ChatOpenAI, ChatMistral, ChatAnthropic, ChatGoogleGenerativeAI, ChatVertexAI, GroqChat",
                        "id": "seqStart_0-input-model-BaseChatModel"
                    },
                    {
                        "label": "Agent Memory",
                        "name": "agentMemory",
                        "type": "BaseCheckpointSaver",
                        "description": "Save the state of the agent",
                        "optional": true,
                        "id": "seqStart_0-input-agentMemory-BaseCheckpointSaver"
                    },
                    {
                        "label": "State",
                        "name": "state",
                        "type": "State",
                        "description": "State is an object that is updated by nodes in the graph, passing from one node to another. By default, state contains \"messages\" that got updated with each message sent and received.",
                        "optional": true,
                        "id": "seqStart_0-input-state-State"
                    },
                    {
                        "label": "Input Moderation",
                        "description": "Detect text that could generate harmful output and prevent it from being sent to the language model",
                        "name": "inputModeration",
                        "type": "Moderation",
                        "optional": true,
                        "list": true,
                        "id": "seqStart_0-input-inputModeration-Moderation"
                    }
                ],
                "inputs": {
                    "model": "{{chatOpenAI_0.data.instance}}",
                    "agentMemory": "{{agentMemory_0.data.instance}}",
                    "state": "{{seqState_0.data.instance}}",
                    "inputModeration": ""
                },
                "outputAnchors": [
                    {
                        "id": "seqStart_0-output-seqStart-Start",
                        "name": "seqStart",
                        "label": "Start",
                        "description": "Starting point of the conversation",
                        "type": "Start"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 382,
            "selected": false,
            "positionAbsolute": {
                "x": 60.339339995889304,
                "y": 396.3093919995337
            },
            "dragging": false
        },
        {
            "id": "seqCondition_0",
            "position": {
                "x": 418.50150866955073,
                "y": 359.1649820890334
            },
            "type": "customNode",
            "data": {
                "id": "seqCondition_0",
                "label": "Condition",
                "version": 2,
                "name": "seqCondition",
                "type": "Condition",
                "baseClasses": ["Condition"],
                "category": "Sequential Agents",
                "description": "Conditional function to determine which route to take next",
                "inputParams": [
                    {
                        "label": "Condition Name",
                        "name": "conditionName",
                        "type": "string",
                        "optional": true,
                        "placeholder": "If X, then Y",
                        "id": "seqCondition_0-input-conditionName-string"
                    },
                    {
                        "label": "Condition",
                        "name": "condition",
                        "type": "conditionFunction",
                        "tabIdentifier": "selectedConditionFunctionTab",
                        "tabs": [
                            {
                                "label": "Condition (Table)",
                                "name": "conditionUI",
                                "type": "datagrid",
                                "description": "If a condition is met, the node connected to the respective output will be executed",
                                "optional": true,
                                "datagrid": [
                                    {
                                        "field": "variable",
                                        "headerName": "Variable",
                                        "type": "freeSolo",
                                        "editable": true,
                                        "loadMethod": ["getPreviousMessages", "loadStateKeys"],
                                        "valueOptions": [
                                            {
                                                "label": "Total Messages (number)",
                                                "value": "$flow.state.messages.length"
                                            },
                                            {
                                                "label": "First Message Content (string)",
                                                "value": "$flow.state.messages[0].content"
                                            },
                                            {
                                                "label": "Last Message Content (string)",
                                                "value": "$flow.state.messages[-1].content"
                                            },
                                            {
                                                "label": "Global variable (string)",
                                                "value": "$vars.<variable-name>"
                                            }
                                        ],
                                        "flex": 0.5,
                                        "minWidth": 200
                                    },
                                    {
                                        "field": "operation",
                                        "headerName": "Operation",
                                        "type": "singleSelect",
                                        "valueOptions": [
                                            "Contains",
                                            "Not Contains",
                                            "Start With",
                                            "End With",
                                            "Is",
                                            "Is Not",
                                            "Is Empty",
                                            "Is Not Empty",
                                            "Greater Than",
                                            "Less Than",
                                            "Equal To",
                                            "Not Equal To",
                                            "Greater Than or Equal To",
                                            "Less Than or Equal To"
                                        ],
                                        "editable": true,
                                        "flex": 0.4,
                                        "minWidth": 150
                                    },
                                    {
                                        "field": "value",
                                        "headerName": "Value",
                                        "flex": 1,
                                        "editable": true
                                    },
                                    {
                                        "field": "output",
                                        "headerName": "Output Name",
                                        "editable": true,
                                        "flex": 0.3,
                                        "minWidth": 150
                                    }
                                ]
                            },
                            {
                                "label": "Condition (Code)",
                                "name": "conditionFunction",
                                "type": "code",
                                "description": "Function to evaluate the condition",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\n1. Must return a string value at the end of function. For example:\n    ```js\n    if (\"X\" === \"X\") {\n        return \"Agent\"; // connect to next agent node\n    } else {\n        return \"End\"; // connect to end node\n    }\n    ```\n\n2. In most cases, you would probably get the last message to do some comparison. You can get all current messages from the state: `$flow.state.messages`:\n    ```json\n    [\n        {\n            \"content\": \"Hello! How can I assist you today?\",\n            \"name\": \"\",\n            \"additional_kwargs\": {},\n            \"response_metadata\": {},\n            \"tool_calls\": [],\n            \"invalid_tool_calls\": [],\n            \"usage_metadata\": {}\n        }\n    ]\n    ```\n\n    For example, to get the last message content:\n    ```js\n    const messages = $flow.state.messages;\n    const lastMessage = messages[messages.length - 1];\n\n    // Proceed to do something with the last message content\n    ```\n\n3. You can get default flow config, including the current \"state\":\n    - `$flow.sessionId`\n    - `$flow.chatId`\n    - `$flow.chatflowId`\n    - `$flow.input`\n    - `$flow.state`\n\n4. You can get custom variables: `$vars.<variable-name>`\n\n"
                                },
                                "hideCodeExecute": true,
                                "codeExample": "const state = $flow.state;\n                \nconst messages = state.messages;\n\nconst lastMessage = messages[messages.length - 1];\n\n/* Check if the last message has content */\nif (lastMessage.content) {\n    return \"Agent\";\n}\n\nreturn \"End\";",
                                "optional": true
                            }
                        ],
                        "id": "seqCondition_0-input-condition-conditionFunction"
                    }
                ],
                "inputAnchors": [
                    {
                        "label": "Start | Agent | LLM | Tool Node",
                        "name": "sequentialNode",
                        "type": "Start | Agent | LLMNode | ToolNode",
                        "list": true,
                        "id": "seqCondition_0-input-sequentialNode-Start | Agent | LLMNode | ToolNode"
                    }
                ],
                "inputs": {
                    "conditionName": "If user has been verified",
                    "sequentialNode": ["{{seqStart_0.data.instance}}"],
                    "condition": "",
                    "selectedConditionFunctionTab_seqCondition_0": "conditionUI",
                    "conditionUI": "[{\"variable\":\"$flow.state.userInfo\",\"operation\":\"Is Not Empty\",\"value\":\"\",\"output\":\"Concierge\",\"actions\":\"\",\"id\":0}]"
                },
                "outputAnchors": [
                    {
                        "name": "output",
                        "label": "Output",
                        "type": "options",
                        "description": "",
                        "options": [
                            {
                                "id": "seqCondition_0-output-concierge-Condition",
                                "name": "concierge",
                                "label": "Concierge",
                                "type": "Condition",
                                "isAnchor": true
                            },
                            {
                                "id": "seqCondition_0-output-end-Condition",
                                "name": "end",
                                "label": "End",
                                "type": "Condition",
                                "isAnchor": true
                            }
                        ],
                        "default": "next"
                    }
                ],
                "outputs": {
                    "output": "next"
                },
                "selected": false
            },
            "width": 300,
            "height": 474,
            "selected": false,
            "positionAbsolute": {
                "x": 418.50150866955073,
                "y": 359.1649820890334
            },
            "dragging": false
        },
        {
            "id": "chatOpenAI_0",
            "position": {
                "x": -316.6467912940658,
                "y": -116.400365380332
            },
            "type": "customNode",
            "data": {
                "id": "chatOpenAI_0",
                "label": "ChatOpenAI",
                "version": 6,
                "name": "chatOpenAI",
                "type": "ChatOpenAI",
                "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"],
                "category": "Chat Models",
                "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
                "inputParams": [
                    {
                        "label": "Connect Credential",
                        "name": "credential",
                        "type": "credential",
                        "credentialNames": ["openAIApi"],
                        "id": "chatOpenAI_0-input-credential-credential"
                    },
                    {
                        "label": "Model Name",
                        "name": "modelName",
                        "type": "asyncOptions",
                        "loadMethod": "listModels",
                        "default": "gpt-3.5-turbo",
                        "id": "chatOpenAI_0-input-modelName-asyncOptions"
                    },
                    {
                        "label": "Temperature",
                        "name": "temperature",
                        "type": "number",
                        "step": 0.1,
                        "default": 0.9,
                        "optional": true,
                        "id": "chatOpenAI_0-input-temperature-number"
                    },
                    {
                        "label": "Max Tokens",
                        "name": "maxTokens",
                        "type": "number",
                        "step": 1,
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-maxTokens-number"
                    },
                    {
                        "label": "Top Probability",
                        "name": "topP",
                        "type": "number",
                        "step": 0.1,
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-topP-number"
                    },
                    {
                        "label": "Frequency Penalty",
                        "name": "frequencyPenalty",
                        "type": "number",
                        "step": 0.1,
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-frequencyPenalty-number"
                    },
                    {
                        "label": "Presence Penalty",
                        "name": "presencePenalty",
                        "type": "number",
                        "step": 0.1,
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-presencePenalty-number"
                    },
                    {
                        "label": "Timeout",
                        "name": "timeout",
                        "type": "number",
                        "step": 1,
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-timeout-number"
                    },
                    {
                        "label": "BasePath",
                        "name": "basepath",
                        "type": "string",
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-basepath-string"
                    },
                    {
                        "label": "BaseOptions",
                        "name": "baseOptions",
                        "type": "json",
                        "optional": true,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-baseOptions-json"
                    },
                    {
                        "label": "Allow Image Uploads",
                        "name": "allowImageUploads",
                        "type": "boolean",
                        "description": "Automatically uses gpt-4-vision-preview when image is being uploaded from chat. Only works with LLMChain, Conversation Chain, ReAct Agent, and Conversational Agent",
                        "default": false,
                        "optional": true,
                        "id": "chatOpenAI_0-input-allowImageUploads-boolean"
                    },
                    {
                        "label": "Image Resolution",
                        "description": "This parameter controls the resolution in which the model views the image.",
                        "name": "imageResolution",
                        "type": "options",
                        "options": [
                            {
                                "label": "Low",
                                "name": "low"
                            },
                            {
                                "label": "High",
                                "name": "high"
                            },
                            {
                                "label": "Auto",
                                "name": "auto"
                            }
                        ],
                        "default": "low",
                        "optional": false,
                        "additionalParams": true,
                        "id": "chatOpenAI_0-input-imageResolution-options"
                    }
                ],
                "inputAnchors": [
                    {
                        "label": "Cache",
                        "name": "cache",
                        "type": "BaseCache",
                        "optional": true,
                        "id": "chatOpenAI_0-input-cache-BaseCache"
                    }
                ],
                "inputs": {
                    "cache": "",
                    "modelName": "gpt-4o",
                    "temperature": "0",
                    "maxTokens": "",
                    "topP": "",
                    "frequencyPenalty": "",
                    "presencePenalty": "",
                    "timeout": "",
                    "basepath": "",
                    "baseOptions": "",
                    "allowImageUploads": "",
                    "imageResolution": "low"
                },
                "outputAnchors": [
                    {
                        "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable",
                        "name": "chatOpenAI",
                        "label": "ChatOpenAI",
                        "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
                        "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | Runnable"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 669,
            "selected": false,
            "positionAbsolute": {
                "x": -316.6467912940658,
                "y": -116.400365380332
            },
            "dragging": false
        },
        {
            "id": "seqAgent_1",
            "position": {
                "x": 773.440353076265,
                "y": 704.2239496316087
            },
            "type": "customNode",
            "data": {
                "id": "seqAgent_1",
                "label": "Agent",
                "version": 2,
                "name": "seqAgent",
                "type": "Agent",
                "baseClasses": ["Agent"],
                "category": "Sequential Agents",
                "description": "Agent that can execute tools",
                "inputParams": [
                    {
                        "label": "Agent Name",
                        "name": "agentName",
                        "type": "string",
                        "placeholder": "Agent",
                        "id": "seqAgent_1-input-agentName-string"
                    },
                    {
                        "label": "System Prompt",
                        "name": "systemMessagePrompt",
                        "type": "string",
                        "rows": 4,
                        "optional": true,
                        "default": "You are a research assistant who can search for up-to-date info using search engine.",
                        "id": "seqAgent_1-input-systemMessagePrompt-string"
                    },
                    {
                        "label": "Human Prompt",
                        "name": "humanMessagePrompt",
                        "type": "string",
                        "description": "This prompt will be added at the end of the messages as human message",
                        "rows": 4,
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_1-input-humanMessagePrompt-string"
                    },
                    {
                        "label": "Require Approval",
                        "name": "interrupt",
                        "description": "Require approval before executing tools. Will proceed when tools are not called",
                        "type": "boolean",
                        "optional": true,
                        "id": "seqAgent_1-input-interrupt-boolean"
                    },
                    {
                        "label": "Format Prompt Values",
                        "name": "promptValues",
                        "description": "Assign values to the prompt variables. You can also use $flow.state.<variable-name> to get the state value",
                        "type": "json",
                        "optional": true,
                        "acceptVariable": true,
                        "list": true,
                        "id": "seqAgent_1-input-promptValues-json"
                    },
                    {
                        "label": "Approval Prompt",
                        "name": "approvalPrompt",
                        "description": "Prompt for approval. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "You are about to execute tool: {tools}. Ask if user want to proceed",
                        "rows": 4,
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_1-input-approvalPrompt-string"
                    },
                    {
                        "label": "Approve Button Text",
                        "name": "approveButtonText",
                        "description": "Text for approve button. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "Yes",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_1-input-approveButtonText-string"
                    },
                    {
                        "label": "Reject Button Text",
                        "name": "rejectButtonText",
                        "description": "Text for reject button. Only applicable if \"Require Approval\" is enabled",
                        "type": "string",
                        "default": "No",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_1-input-rejectButtonText-string"
                    },
                    {
                        "label": "Update State",
                        "name": "updateStateMemory",
                        "type": "tabs",
                        "tabIdentifier": "selectedUpdateStateMemoryTab",
                        "additionalParams": true,
                        "default": "updateStateMemoryUI",
                        "tabs": [
                            {
                                "label": "Update State (Table)",
                                "name": "updateStateMemoryUI",
                                "type": "datagrid",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\n1. Key and value pair to be updated. For example: if you have the following State:\n    | Key       | Operation     | Default Value     |\n    |-----------|---------------|-------------------|\n    | user      | Replace       |                   |\n\n    You can update the \"user\" value with the following:\n    | Key       | Value     |\n    |-----------|-----------|\n    | user      | john doe  |\n\n2. If you want to use the agent's output as the value to update state, it is available as available as `$flow.output` with the following structure:\n    ```json\n    {\n        \"output\": \"Hello! How can I assist you today?\",\n        \"usedTools\": [\n            {\n                \"tool\": \"tool-name\",\n                \"toolInput\": \"{foo: var}\",\n                \"toolOutput\": \"This is the tool's output\"\n            }\n        ],\n        \"sourceDocuments\": [\n            {\n                \"pageContent\": \"This is the page content\",\n                \"metadata\": \"{foo: var}\",\n            }\n        ],\n    }\n    ```\n\n    For example, if the `toolOutput` is the value you want to update the state with, you can do the following:\n    | Key       | Value                                     |\n    |-----------|-------------------------------------------|\n    | user      | `$flow.output.usedTools[0].toolOutput`  |\n\n3. You can get default flow config, including the current \"state\":\n    - `$flow.sessionId`\n    - `$flow.chatId`\n    - `$flow.chatflowId`\n    - `$flow.input`\n    - `$flow.state`\n\n4. You can get custom variables: `$vars.<variable-name>`\n\n"
                                },
                                "description": "This is only applicable when you have a custom State at the START node. After agent execution, you might want to update the State values",
                                "datagrid": [
                                    {
                                        "field": "key",
                                        "headerName": "Key",
                                        "type": "asyncSingleSelect",
                                        "loadMethod": "loadStateKeys",
                                        "flex": 0.5,
                                        "editable": true
                                    },
                                    {
                                        "field": "value",
                                        "headerName": "Value",
                                        "type": "freeSolo",
                                        "valueOptions": [
                                            {
                                                "label": "Agent Output (string)",
                                                "value": "$flow.output.content"
                                            },
                                            {
                                                "label": "Used Tools (array)",
                                                "value": "$flow.output.usedTools"
                                            },
                                            {
                                                "label": "First Tool Output (string)",
                                                "value": "$flow.output.usedTools[0].toolOutput"
                                            },
                                            {
                                                "label": "Source Documents (array)",
                                                "value": "$flow.output.sourceDocuments"
                                            },
                                            {
                                                "label": "Global variable (string)",
                                                "value": "$vars.<variable-name>"
                                            },
                                            {
                                                "label": "Input Question (string)",
                                                "value": "$flow.input"
                                            },
                                            {
                                                "label": "Session Id (string)",
                                                "value": "$flow.sessionId"
                                            },
                                            {
                                                "label": "Chat Id (string)",
                                                "value": "$flow.chatId"
                                            },
                                            {
                                                "label": "Chatflow Id (string)",
                                                "value": "$flow.chatflowId"
                                            }
                                        ],
                                        "editable": true,
                                        "flex": 1
                                    }
                                ],
                                "optional": true,
                                "additionalParams": true
                            },
                            {
                                "label": "Update State (Code)",
                                "name": "updateStateMemoryCode",
                                "type": "code",
                                "hint": {
                                    "label": "How to use",
                                    "value": "\n1. Return the key value JSON object. For example: if you have the following State:\n    ```json\n    {\n        \"user\": null\n    }\n    ```\n\n    You can update the \"user\" value by returning the following:\n    ```js\n    return {\n        \"user\": \"john doe\"\n    }\n    ```\n\n2. If you want to use the agent's output as the value to update state, it is available as `$flow.output` with the following structure:\n    ```json\n    {\n        \"content\": \"Hello! How can I assist you today?\",\n        \"usedTools\": [\n            {\n                \"tool\": \"tool-name\",\n                \"toolInput\": \"{foo: var}\",\n                \"toolOutput\": \"This is the tool's output\"\n            }\n        ],\n        \"sourceDocuments\": [\n            {\n                \"pageContent\": \"This is the page content\",\n                \"metadata\": \"{foo: var}\",\n            }\n        ],\n    }\n    ```\n\n    For example, if the `toolOutput` is the value you want to update the state with, you can return the following:\n    ```js\n    return {\n        \"user\": $flow.output.usedTools[0].toolOutput\n    }\n    ```\n\n3. You can also get default flow config, including the current \"state\":\n    - `$flow.sessionId`\n    - `$flow.chatId`\n    - `$flow.chatflowId`\n    - `$flow.input`\n    - `$flow.state`\n\n4. You can get custom variables: `$vars.<variable-name>`\n\n"
                                },
                                "description": "This is only applicable when you have a custom State at the START node. After agent execution, you might want to update the State values. Must return an object representing the state",
                                "hideCodeExecute": true,
                                "codeExample": "const result = $flow.output;\n\n/* Suppose we have a custom State schema like this:\n* {\n    aggregate: {\n        value: (x, y) => x.concat(y),\n        default: () => []\n    }\n  }\n*/\n\nreturn {\n  aggregate: [result.content]\n};",
                                "optional": true,
                                "additionalParams": true
                            }
                        ],
                        "id": "seqAgent_1-input-updateStateMemory-tabs"
                    },
                    {
                        "label": "Max Iterations",
                        "name": "maxIterations",
                        "type": "number",
                        "optional": true,
                        "additionalParams": true,
                        "id": "seqAgent_1-input-maxIterations-number"
                    }
                ],
                "inputAnchors": [
                    {
                        "label": "Tools",
                        "name": "tools",
                        "type": "Tool",
                        "list": true,
                        "optional": true,
                        "id": "seqAgent_1-input-tools-Tool"
                    },
                    {
                        "label": "Start | Agent | Condition | LLM | Tool Node",
                        "name": "sequentialNode",
                        "type": "Start | Agent | Condition | LLMNode | ToolNode",
                        "list": true,
                        "id": "seqAgent_1-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode"
                    },
                    {
                        "label": "Chat Model",
                        "name": "model",
                        "type": "BaseChatModel",
                        "optional": true,
                        "description": "Overwrite model to be used for this agent",
                        "id": "seqAgent_1-input-model-BaseChatModel"
                    }
                ],
                "inputs": {
                    "agentName": "Identity Verification",
                    "systemMessagePrompt": "You are an Identity Verfication Specialist in the Patient Concierge system. You job is to verify the identity of the patient before any questions about their upcoming procedure can be addressed.\n\nBegin by greeting the patient and informing them that they need to verify their identity before proceeding. If verification is successful, allow the patient to ask questions about their procedure. If verification fails, kindly inform the patient and offer assistance for re-verification. Make sure both the patient name and date of birth matches records in the patient identity database before proceeding (\"patient_name\", \"date_of_birth\")\n\nSteps:\n1. Greet the patient.\n2. Inform them about the need for identity verification.\n3. Request the patient's full name and date of birth.\n4. Verify the information against the records.\n5. If verification is successful, handle any questions about the upcoming procedure.\n6. If verification fails, provide appropriate instructions or assistance.\n\nExample Interaction:\n1. “To verify your identity, please provide your full name and date of birth.”\n2. If verification is successful:\n    - “Thank you for verifying your identity. How can I assist you with your upcoming procedure?”\n3. If verification fails:\n    - “I’m sorry, but your identity could not be verified. Please try again or contact support for assistance.”\n\nUse the function tool \"patient_identity_database\" to verify identity. User might give date of birth in different format, be smart and convert it into MM-DD-YYYY format. When verifying identity, if the information does not match, reply with \"Sorry your information is not in our database.\"",
                    "humanMessagePrompt": "",
                    "tools": ["{{customTool_0.data.instance}}"],
                    "sequentialNode": ["{{seqCondition_0.data.instance}}", "{{seqCondition_0.data.instance}}"],
                    "model": "",
                    "interrupt": "",
                    "promptValues": "",
                    "approvalPrompt": "You are about to execute tool: {tools}. Ask if user want to proceed",
                    "approveButtonText": "Yes",
                    "rejectButtonText": "No",
                    "updateStateMemory": "updateStateMemoryUI",
                    "maxIterations": "",
                    "selectedUpdateStateMemoryTab_seqAgent_1": "updateStateMemoryCode",
                    "updateStateMemoryCode": "const result = $flow.output;\nconst usedTools = result.usedTools ?? [];\n\n// Check if correct tool is being used\nconst calledTool =  usedTools.find((usedTool) => usedTool.tool === \"patient_identity_database\");\nif (!calledTool) return {};\n\n\ntry {\n  const parsedToolOutput = JSON.parse(calledTool.toolOutput);\n  return {\n    userInfo: parsedToolOutput // parsing tool output since its always string\n  };\n} catch (e) {\n  return {};\n}\n"
                },
                "outputAnchors": [
                    {
                        "id": "seqAgent_1-output-seqAgent-Agent",
                        "name": "seqAgent",
                        "label": "Agent",
                        "description": "Agent that can execute tools",
                        "type": "Agent"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 877,
            "selected": false,
            "positionAbsolute": {
                "x": 773.440353076265,
                "y": 704.2239496316087
            },
            "dragging": false
        },
        {
            "id": "agentMemory_0",
            "position": {
                "x": -664.9588570520918,
                "y": 414.31066847998807
            },
            "type": "customNode",
            "data": {
                "id": "agentMemory_0",
                "label": "Agent Memory",
                "version": 1,
                "name": "agentMemory",
                "type": "AgentMemory",
                "baseClasses": ["AgentMemory", "BaseCheckpointSaver"],
                "category": "Memory",
                "description": "Memory for agentflow to remember the state of the conversation",
                "inputParams": [
                    {
                        "label": "Database",
                        "name": "databaseType",
                        "type": "options",
                        "options": [
                            {
                                "label": "SQLite",
                                "name": "sqlite"
                            }
                        ],
                        "default": "sqlite",
                        "id": "agentMemory_0-input-databaseType-options"
                    },
                    {
                        "label": "Database File Path",
                        "name": "databaseFilePath",
                        "type": "string",
                        "placeholder": "C:\\Users\\User\\.flowise\\database.sqlite",
                        "description": "If SQLite is selected, provide the path to the SQLite database file. Leave empty to use default application database",
                        "additionalParams": true,
                        "optional": true,
                        "id": "agentMemory_0-input-databaseFilePath-string"
                    },
                    {
                        "label": "Additional Connection Configuration",
                        "name": "additionalConfig",
                        "type": "json",
                        "additionalParams": true,
                        "optional": true,
                        "id": "agentMemory_0-input-additionalConfig-json"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "databaseType": "sqlite",
                    "databaseFilePath": "",
                    "additionalConfig": ""
                },
                "outputAnchors": [
                    {
                        "id": "agentMemory_0-output-agentMemory-AgentMemory|BaseCheckpointSaver",
                        "name": "agentMemory",
                        "label": "AgentMemory",
                        "description": "Memory for agentflow to remember the state of the conversation",
                        "type": "AgentMemory | BaseCheckpointSaver"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 327,
            "selected": false,
            "positionAbsolute": {
                "x": -664.9588570520918,
                "y": 414.31066847998807
            },
            "dragging": false
        },
        {
            "id": "customTool_0",
            "position": {
                "x": 416.23687182130743,
                "y": 976.6695917973606
            },
            "type": "customNode",
            "data": {
                "id": "customTool_0",
                "label": "Custom Tool",
                "version": 1,
                "name": "customTool",
                "type": "CustomTool",
                "baseClasses": ["CustomTool", "Tool", "StructuredTool", "Runnable"],
                "category": "Tools",
                "description": "Use custom tool you've created in Flowise within chatflow",
                "inputParams": [
                    {
                        "label": "Select Tool",
                        "name": "selectedTool",
                        "type": "asyncOptions",
                        "loadMethod": "listTools",
                        "id": "customTool_0-input-selectedTool-asyncOptions"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "selectedTool": "29e51b55-6d5a-4f4f-9376-a864a62004cb"
                },
                "outputAnchors": [
                    {
                        "id": "customTool_0-output-customTool-CustomTool|Tool|StructuredTool|Runnable",
                        "name": "customTool",
                        "label": "CustomTool",
                        "description": "Use custom tool you've created in Flowise within chatflow",
                        "type": "CustomTool | Tool | StructuredTool | Runnable"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 285,
            "selected": false,
            "positionAbsolute": {
                "x": 416.23687182130743,
                "y": 976.6695917973606
            },
            "dragging": false
        },
        {
            "id": "customTool_1",
            "position": {
                "x": 406.451652299109,
                "y": -94.73117951029039
            },
            "type": "customNode",
            "data": {
                "id": "customTool_1",
                "label": "Custom Tool",
                "version": 1,
                "name": "customTool",
                "type": "CustomTool",
                "baseClasses": ["CustomTool", "Tool", "StructuredTool", "Runnable"],
                "category": "Tools",
                "description": "Use custom tool you've created in Flowise within chatflow",
                "inputParams": [
                    {
                        "label": "Select Tool",
                        "name": "selectedTool",
                        "type": "asyncOptions",
                        "loadMethod": "listTools",
                        "id": "customTool_1-input-selectedTool-asyncOptions"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "selectedTool": "f0ea4e6b-d95d-4554-8270-d8e31b393243"
                },
                "outputAnchors": [
                    {
                        "id": "customTool_1-output-customTool-CustomTool|Tool|StructuredTool|Runnable",
                        "name": "customTool",
                        "label": "CustomTool",
                        "description": "Use custom tool you've created in Flowise within chatflow",
                        "type": "CustomTool | Tool | StructuredTool | Runnable"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 285,
            "selected": false,
            "positionAbsolute": {
                "x": 406.451652299109,
                "y": -94.73117951029039
            },
            "dragging": false
        },
        {
            "id": "seqEnd_1",
            "position": {
                "x": 1141.757749450836,
                "y": 1414.623363880458
            },
            "type": "customNode",
            "data": {
                "id": "seqEnd_1",
                "label": "End",
                "version": 2,
                "name": "seqEnd",
                "type": "End",
                "baseClasses": ["End"],
                "category": "Sequential Agents",
                "description": "End conversation",
                "inputParams": [],
                "inputAnchors": [
                    {
                        "label": "Agent | Condition | LLM | Tool Node",
                        "name": "sequentialNode",
                        "type": "Agent | Condition | LLMNode | ToolNode",
                        "id": "seqEnd_1-input-sequentialNode-Agent | Condition | LLMNode | ToolNode"
                    }
                ],
                "inputs": {
                    "sequentialNode": "{{seqAgent_1.data.instance}}"
                },
                "outputAnchors": [],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 143,
            "positionAbsolute": {
                "x": 1141.757749450836,
                "y": 1414.623363880458
            },
            "selected": false,
            "dragging": false
        },
        {
            "id": "stickyNote_0",
            "position": {
                "x": -665.6866144784351,
                "y": 122.6151050654218
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_0",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_0-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "The goal of this flow is to verify user information before proceeding to answer any question.\n\nWe can achieve this by:\n1. Create a new state (userInfo) to save user information\n2. Check if \"userInfo\" is null\n3. If null, route to Identity Agent\n4. If already set, meaning user has been verified, route to Concierge Agent"
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_0-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 243,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": -665.6866144784351,
                "y": 122.6151050654218
            }
        },
        {
            "id": "stickyNote_1",
            "position": {
                "x": -339.86543232618214,
                "y": 980.9996530446099
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_1",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_1-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "Create a new state - \"userInfo\""
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_1-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 42,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": -339.86543232618214,
                "y": 980.9996530446099
            }
        },
        {
            "id": "stickyNote_2",
            "position": {
                "x": 415.9580351096404,
                "y": 231.37156153655695
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_2",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_2-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "Check if \"userInfo\" is null\n\n- If null, route to \"End\"\n- If set, route to \"Concierge\""
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_2-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 103,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": 415.9580351096404,
                "y": 231.37156153655695
            }
        },
        {
            "id": "stickyNote_3",
            "position": {
                "x": 408.7424009388817,
                "y": 892.6619076258235
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_3",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_3-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "This tool is used to check if there is a matching record from database"
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_3-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 62,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": 408.7424009388817,
                "y": 892.6619076258235
            }
        },
        {
            "id": "stickyNote_4",
            "position": {
                "x": 403.52168768028207,
                "y": -333.85766059447906
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_4",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_4-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "When this tool is being used, that means \"userInfo\" was successfully updated by Identity Agent.\n\nWe can then use the saved \"userInfo\" to find additional data.\n\nFor example, if \"userInfo\" is an object containing \"userID\", we can use it to lookup other info from another table"
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_4-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 223,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": 403.52168768028207,
                "y": -333.85766059447906
            }
        },
        {
            "id": "stickyNote_5",
            "position": {
                "x": 1102.8425811733184,
                "y": 196.9148540298005
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_5",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_5-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "This agent is designed to answer user question using the tool"
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_5-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 62,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": 1102.8425811733184,
                "y": 196.9148540298005
            }
        },
        {
            "id": "stickyNote_6",
            "position": {
                "x": 1108.063294431918,
                "y": 964.0116554933495
            },
            "type": "stickyNote",
            "data": {
                "id": "stickyNote_6",
                "label": "Sticky Note",
                "version": 2,
                "name": "stickyNote",
                "type": "StickyNote",
                "baseClasses": ["StickyNote"],
                "tags": ["Utilities"],
                "category": "Utilities",
                "description": "Add a sticky note",
                "inputParams": [
                    {
                        "label": "",
                        "name": "note",
                        "type": "string",
                        "rows": 1,
                        "placeholder": "Type something here",
                        "optional": true,
                        "id": "stickyNote_6-input-note-string"
                    }
                ],
                "inputAnchors": [],
                "inputs": {
                    "note": "This agent is designed to ask for user details, in order to check if user exists in database.\n\nIn the \"Additional Parameters\" -> \"Update State\", if the tool successfully found a matching record, we update \"userInfo\" state.\n\nOtherwise, we return an empty object"
                },
                "outputAnchors": [
                    {
                        "id": "stickyNote_6-output-stickyNote-StickyNote",
                        "name": "stickyNote",
                        "label": "StickyNote",
                        "description": "Add a sticky note",
                        "type": "StickyNote"
                    }
                ],
                "outputs": {},
                "selected": false
            },
            "width": 300,
            "height": 223,
            "selected": false,
            "dragging": false,
            "positionAbsolute": {
                "x": 1108.063294431918,
                "y": 964.0116554933495
            }
        }
    ],
    "edges": [
        {
            "source": "seqState_0",
            "sourceHandle": "seqState_0-output-seqState-State",
            "target": "seqStart_0",
            "targetHandle": "seqStart_0-input-state-State",
            "type": "buttonedge",
            "id": "seqState_0-seqState_0-output-seqState-State-seqStart_0-seqStart_0-input-state-State"
        },
        {
            "source": "agentMemory_0",
            "sourceHandle": "agentMemory_0-output-agentMemory-AgentMemory|BaseCheckpointSaver",
            "target": "seqStart_0",
            "targetHandle": "seqStart_0-input-agentMemory-BaseCheckpointSaver",
            "type": "buttonedge",
            "id": "agentMemory_0-agentMemory_0-output-agentMemory-AgentMemory|BaseCheckpointSaver-seqStart_0-seqStart_0-input-agentMemory-BaseCheckpointSaver"
        },
        {
            "source": "chatOpenAI_0",
            "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable",
            "target": "seqStart_0",
            "targetHandle": "seqStart_0-input-model-BaseChatModel",
            "type": "buttonedge",
            "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable-seqStart_0-seqStart_0-input-model-BaseChatModel"
        },
        {
            "source": "seqStart_0",
            "sourceHandle": "seqStart_0-output-seqStart-Start",
            "target": "seqCondition_0",
            "targetHandle": "seqCondition_0-input-sequentialNode-Start | Agent | LLMNode | ToolNode",
            "type": "buttonedge",
            "id": "seqStart_0-seqStart_0-output-seqStart-Start-seqCondition_0-seqCondition_0-input-sequentialNode-Start | Agent | LLMNode | ToolNode"
        },
        {
            "source": "customTool_0",
            "sourceHandle": "customTool_0-output-customTool-CustomTool|Tool|StructuredTool|Runnable",
            "target": "seqAgent_1",
            "targetHandle": "seqAgent_1-input-tools-Tool",
            "type": "buttonedge",
            "id": "customTool_0-customTool_0-output-customTool-CustomTool|Tool|StructuredTool|Runnable-seqAgent_1-seqAgent_1-input-tools-Tool"
        },
        {
            "source": "customTool_1",
            "sourceHandle": "customTool_1-output-customTool-CustomTool|Tool|StructuredTool|Runnable",
            "target": "seqAgent_0",
            "targetHandle": "seqAgent_0-input-tools-Tool",
            "type": "buttonedge",
            "id": "customTool_1-customTool_1-output-customTool-CustomTool|Tool|StructuredTool|Runnable-seqAgent_0-seqAgent_0-input-tools-Tool"
        },
        {
            "source": "seqAgent_0",
            "sourceHandle": "seqAgent_0-output-seqAgent-Agent",
            "target": "seqEnd_0",
            "targetHandle": "seqEnd_0-input-sequentialNode-Agent | Condition | LLMNode | ToolNode",
            "type": "buttonedge",
            "id": "seqAgent_0-seqAgent_0-output-seqAgent-Agent-seqEnd_0-seqEnd_0-input-sequentialNode-Agent | Condition | LLMNode | ToolNode"
        },
        {
            "source": "seqAgent_1",
            "sourceHandle": "seqAgent_1-output-seqAgent-Agent",
            "target": "seqEnd_1",
            "targetHandle": "seqEnd_1-input-sequentialNode-Agent | Condition | LLMNode | ToolNode",
            "type": "buttonedge",
            "id": "seqAgent_1-seqAgent_1-output-seqAgent-Agent-seqEnd_1-seqEnd_1-input-sequentialNode-Agent | Condition | LLMNode | ToolNode"
        },
        {
            "source": "seqCondition_0",
            "sourceHandle": "seqCondition_0-output-concierge-Condition",
            "target": "seqAgent_0",
            "targetHandle": "seqAgent_0-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode",
            "type": "buttonedge",
            "id": "seqCondition_0-seqCondition_0-output-concierge-Condition-seqAgent_0-seqAgent_0-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode"
        },
        {
            "source": "seqCondition_0",
            "sourceHandle": "seqCondition_0-output-end-Condition",
            "target": "seqAgent_1",
            "targetHandle": "seqAgent_1-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode",
            "type": "buttonedge",
            "id": "seqCondition_0-seqCondition_0-output-end-Condition-seqAgent_1-seqAgent_1-input-sequentialNode-Start | Agent | Condition | LLMNode | ToolNode"
        }
    ]
}
